package com.nbjtjc.safe.service.emg;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nbjtjc.safe.bean.Constant;
import com.nbjtjc.safe.bean.Page;
import com.nbjtjc.safe.bean.Result;
import com.nbjtjc.safe.job.mapper.ScheduleJobMapper;
import com.nbjtjc.safe.job.model.ScheduleJobEntity;
import com.nbjtjc.safe.mapper.emg.EmgPlanPublicMapper;
import com.nbjtjc.safe.mapper.emg.EmgWorkBriefMapper;
import com.nbjtjc.safe.mapper.sys.SysDeptMapper;
import com.nbjtjc.safe.model.emg.EmgPlanPublic;
import com.nbjtjc.safe.model.emg.EmgWorkBrief;
import com.nbjtjc.safe.model.sys.SysUser;
import com.nbjtjc.safe.util.MyShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class EmgWorkBriefService {
    @Autowired
    private EmgWorkBriefMapper emgWorkBriefMapper;
    @Autowired
    private EmgPlanPublicMapper emgPlanPublicMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private ScheduleJobMapper scheduleJobMapper;
    @Transactional(rollbackFor = {Throwable.class})
    public Result add(EmgWorkBrief emgWorkBrief) {
        Result result = new Result();
        if (isPlanPublicFinished(emgWorkBrief)) {
            result.setFalse("该响应已经完结，无法添加工作简报");
        }
        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("user");
        if (ObjectUtil.isNotNull(sysUser)) {
            emgWorkBrief.setDeptId(sysUser.getDeptId().intValue());
            emgWorkBrief.setReportUserId(sysUser.getUserId());
        }
        if(emgWorkBrief.getStatus().equals(Constant.WorkBriefStatus.PUBLIC.getValue())){
            emgWorkBrief.setReportTime(new Date());
        }
        if (ObjectUtil.isNull(emgWorkBrief) || ObjectUtil.isNull(emgWorkBrief.getDeptId())
                || ObjectUtil.isNull(emgWorkBrief.getReportUserId())) {
            result.setFalse("要创建的简报不能为空，或者缺少必要的id");
        }
        int res = emgWorkBriefMapper.insertSelective(emgWorkBrief);
        if (res == 0) {
            result.setFalse("插入失败");
        }
        result.setData(emgWorkBrief);
        return result;
    }

    //todo 添加工作简报时，关联转发的上下级，简报填一次就够了
    private void checkForwardAndInsert(EmgWorkBrief emgWorkBrief){

    }

    @Transactional(rollbackFor = Throwable.class)
    public Result update(EmgWorkBrief emgWorkBrief) {
        Result result = new Result();
        if (ObjectUtil.isNull(emgWorkBrief) || ObjectUtil.isNull(emgWorkBrief.getWbId())) {
            result.setFalse("关键的id字段不能为空");
            return result;
        }
        if(emgWorkBrief.getStatus().equals(Constant.WorkBriefStatus.PUBLIC.getValue())){
            emgWorkBrief.setReportTime(new Date());
        }
        int res = emgWorkBriefMapper.updateByPrimaryKeySelective(emgWorkBrief);
        if (res == 0) {
            result.setFalse("更新失败");
            return result;
        }
        result.setData(emgWorkBrief);
        return result;
    }

    @Transactional(rollbackFor = {Throwable.class})
    public Result delete(int workBriefId) {
        Result result = new Result();
        emgWorkBriefMapper.deleteByPrimaryKey(workBriefId);
        return result;
    }

    public Result find(EmgWorkBrief emgWorkBrief, Page page) {
        Result result = new Result();
        int planPublicId=0;
        if(ObjectUtil.isNotNull(emgWorkBrief.getPlanPublicId())){
            planPublicId=emgWorkBrief.getPlanPublicId();
        }
        Map<String, Object> data = new HashMap<>();
        if (ObjectUtil.isNotNull(emgWorkBrief.getPlanPublicId())) {
            //方便前端，这里的都会根据planPublicId去获取对应的startPlanPublicId
            emgWorkBrief.setPlanPublicId(emgPlanPublicMapper
                    .getStartPlanPublicId(emgWorkBrief.getPlanPublicId()));
        }
        PageHelper.startPage(page.getPageCurrent(), page.getPageSize());
        //TODO  page分页失效
        List<EmgWorkBrief> emgWorkBriefs = emgWorkBriefMapper.search(emgWorkBrief, page);
        data.put("page", new PageInfo<>(emgWorkBriefs));
        if(CollectionUtil.isNotEmpty(emgWorkBriefs)){
            emgWorkBriefs.forEach(workBrief->{
                ScheduleJobEntity scheduleJobEntity=new ScheduleJobEntity();
                scheduleJobEntity.setIdType(Constant.ScheduleJobIdType.WORKBRIEF.getValue());
                scheduleJobEntity.setBusinessId(workBrief.getWbId());
                scheduleJobEntity= scheduleJobMapper.selectOne(scheduleJobEntity);
                workBrief.setScheduleJobEntity(scheduleJobEntity);
            });
        }
        data.put("latelyReportTime", getMaxDate(emgWorkBriefs,planPublicId));
        result.setData(data);
        return result;
    }

    public Result findOrganize(EmgWorkBrief emgWorkBrief, Page page) {
        Result result = new Result();
        HashMap<String, List<Object>> workInfoMap = new HashMap<>();
        workInfoMap.put("date", new ArrayList<>());
        workInfoMap.put("defenseWork", new ArrayList<>());
        workInfoMap.put("dutyPeople", new ArrayList<>());
        workInfoMap.put("disasterSituation", new ArrayList<>());
        workInfoMap.put("emergency", new ArrayList<>());
        workInfoMap.put("emergencyHandle", new ArrayList<>());
        workInfoMap.put("emergencyAfter", new ArrayList<>());
        Map<String, Object> map = new HashMap<>();

        if (ObjectUtil.isNotNull(emgWorkBrief.getPlanPublicId())) {
            //方便前端，这里的都会根据planPublicId去获取对应的startPlanPublicId
            emgWorkBrief.setPlanPublicId(emgPlanPublicMapper
                    .getStartPlanPublicId(emgWorkBrief.getPlanPublicId()));
        }
        String pathId="";
        if(!planPublicIsCreateSameCompany(emgWorkBrief.getPlanPublicId())
        &&!emgWorkBrief.getCompanyId().equals(MyShiroUtils.getCompanyId())){
            EmgPlanPublic superiorDeptPlanPublic=emgPlanPublicMapper
                    .selectByPrimaryKey(emgWorkBrief.getPlanPublicId());
            EmgPlanPublic emgPlanPublic=new EmgPlanPublic();
            emgPlanPublic.setHistory(0);
            emgPlanPublic.setPathId(superiorDeptPlanPublic.getPathId());
            emgPlanPublic.setCompanyId(MyShiroUtils.getCompanyId());
            emgPlanPublic=emgPlanPublicMapper.selectOne(emgPlanPublic);
            if(ObjectUtil.isNull(emgPlanPublic)){
                result.setFalse("没有上报记录");
                map.put("workBrief", workInfoMap);
                map.put("page", new PageInfo<>());
                result.setData(map);
            }
            emgWorkBrief.setPlanPublicId(emgPlanPublic.getStartPlanId());
        }
        PageHelper.startPage(page.getPageCurrent(), page.getPageSize());
        List<EmgWorkBrief> emgWorkBriefs = emgWorkBriefMapper.search(emgWorkBrief, page);
        emgWorkBriefs.forEach(workBrief -> {
            workInfoMap.get("date").add(workBrief.getReportTime());
            workInfoMap.get("defenseWork").add(workBrief.getDefenseWork());
            workInfoMap.get("dutyPeople").add(workBrief.getDutyPeople());
            workInfoMap.get("disasterSituation").add(workBrief.getDisasterSituation());
            workInfoMap.get("emergency").add(workBrief.getEmergency());
            workInfoMap.get("emergencyHandle").add(workBrief.getEmergencyHandle());
            workInfoMap.get("emergencyAfter").add(workBrief.getEmergencyAfter());
        });
        map.put("workBrief", workInfoMap);
        map.put("page", new PageInfo<>(emgWorkBriefs));
        result.setData(map);
        return result;
    }

    public Result findLowerLevelWorkBrief(EmgWorkBrief emgWorkBrief) {
        Result result = new Result();
        if (ObjectUtil.isNull(emgWorkBrief) || ObjectUtil.isNull(emgWorkBrief.getPlanPublicId())) {
            result.setFalse("关键字段不能为空");
            return result;
        }
       if(planPublicIsCreateSameCompany(emgWorkBrief.getPlanPublicId())){
           result=getPlanCreaterSubWorkBrief(result,emgWorkBrief);
       }else{
           result=getParentCompanyPlanSubWorkBrief(result,emgWorkBrief);
       }
        return result;
    }

    /**
     * 需要记录工作简报的planPublic是不是同一个公司发布的
     * @param planPublicId
     * @return
     */
    private boolean planPublicIsCreateSameCompany(int planPublicId){
        int planPublicCompanyId=emgPlanPublicMapper.getCompanyId(planPublicId);
        if(MyShiroUtils.getCompanyId().equals(planPublicCompanyId)){
            return true;
        }else{
            return false;
        }
    }

    /**
     * planPublic是上级公司发布的，我填写上级发布应急响应的简报时，需要获取我的下级公司填写的简报
     * 首先我根据上级发的planPublic，转发一份到我的下级单位
     * 我转发的应急响应和上级发的都是同一个pathId
     * @return
     */
    private Result getParentCompanyPlanSubWorkBrief(Result result,EmgWorkBrief emgWorkBrief){
        EmgPlanPublic superiorDeptPlanPublic=emgPlanPublicMapper
                .selectByPrimaryKey(emgWorkBrief.getPlanPublicId());
        if(ObjectUtil.isNull(superiorDeptPlanPublic)){
            result.setFalse("没有对应的应急预案");
            return result;
        }
        EmgPlanPublic emgPlanPublic=new EmgPlanPublic();
        emgPlanPublic.setCompanyId(MyShiroUtils.getCompanyId());
        emgPlanPublic.setPathId(superiorDeptPlanPublic.getPathId());
        emgPlanPublic.setHistory(0);
        emgPlanPublic=emgPlanPublicMapper.selectOne(emgPlanPublic);
        if(ObjectUtil.isNull(emgPlanPublic)){
            result.setFalse("当前公司还未转发上级响应给下级");
            return result;
        }
        List<Integer> subCompanyIds = sysDeptMapper.getSubCompanyId(MyShiroUtils.getCompanyId()
        ,Constant.SysDeptType.COMPANY.getValue());
        if (CollectionUtil.isEmpty(subCompanyIds)) {
            result.setFalse("没有子公司");
            return result;
        }
        emgWorkBrief.setCompanyIds(subCompanyIds);
        emgWorkBrief.setPlanPublicId(emgPlanPublic.getId());
        List<EmgWorkBrief> emgWorkBriefs = emgWorkBriefMapper.search(emgWorkBrief, new Page());
        if (CollectionUtil.isEmpty(emgWorkBriefs)) {
            result.setFalse("暂时没有上报数据");
            return result;
        }
        result.setData(compareWorkBrief(emgWorkBriefs));
        return result;
    }


    /**
     * 当前需要记录简报的planPublic是自己发的情况下，获取下一级的工作简报
     */
    private Result getPlanCreaterSubWorkBrief(Result result,EmgWorkBrief emgWorkBrief){
        Map<String, Object> data = new HashMap<>();

        List<Integer> subCompanyIds = sysDeptMapper.getSubCompanyId(MyShiroUtils.getCompanyId()
        ,Constant.SysDeptType.COMPANY.getValue());
        if (CollectionUtil.isEmpty(subCompanyIds)) {
            result.setFalse("没有子公司");
            return result;
        }
        emgWorkBrief.setCompanyIds(subCompanyIds);
        List<EmgWorkBrief> emgWorkBriefs = emgWorkBriefMapper.search(emgWorkBrief, new Page());
        if (CollectionUtil.isEmpty(emgWorkBriefs)) {
            result.setFalse("暂时没有上报数据");
            return result;
        }
        result.setData(compareWorkBrief(emgWorkBriefs));
        return result;
    }

    /**
     * 将工作简报组织
     * @param emgWorkBriefs
     * @return
     */
    private  HashMap<String, List<Map<String, String>>> compareWorkBrief(List<EmgWorkBrief> emgWorkBriefs){
        EmgPlanPublic emgPlanPublic = emgPlanPublicMapper.selectByPrimaryKey
                (emgWorkBriefs.get(0).getPlanPublicId());
        Map<Integer, EmgWorkBrief> emgWorkBriefMap = new HashMap<>();


        emgWorkBriefs.forEach(workBrief -> {
            if (emgWorkBriefMap.containsKey(workBrief.getDeptId())) {
                if (emgWorkBriefMap.get(workBrief.getDeptId()).getReportTime().compareTo(workBrief.getReportTime()) < 0) {
                    emgWorkBriefMap.put(workBrief.getDeptId(), workBrief);
                }
            } else {
                emgWorkBriefMap.put(workBrief.getDeptId(), workBrief);
            }

        });
        List<EmgWorkBrief> latestWorkBirefs = new ArrayList<>(emgWorkBriefMap.values());
        HashMap<String, List<Map<String, String>>> workInfoMap = new HashMap<>();
        initWorkBriefMap(workInfoMap);
        latestWorkBirefs.forEach(workBrief -> {
            Map<String, String> defenseWorkMap = new HashMap<>();
            defenseWorkMap.put("companyName", workBrief.getCompanyName());
            defenseWorkMap.put("date"
                    , DateUtil.format(workBrief.getReportTime(), "yyyy-MM-dd hh:mm:ss"));
            defenseWorkMap.put("content", workBrief.getDefenseWork());
            workInfoMap.get("defenseWork").add(defenseWorkMap);
            Map<String, String> dutyPeopleMap = new HashMap<>();
            dutyPeopleMap.put("companyName", workBrief.getCompanyName());
            dutyPeopleMap.put("date"
                    , DateUtil.format(workBrief.getReportTime(), "yyyy-MM-dd hh:mm:ss"));
            dutyPeopleMap.put("content", workBrief.getDutyPeople());
            workInfoMap.get("dutyPeople").add(dutyPeopleMap);
            Map<String, String> disasterSituationMap = new HashMap<>();
            disasterSituationMap.put("companyName", workBrief.getCompanyName());
            disasterSituationMap.put("date"
                    , DateUtil.format(workBrief.getReportTime(), "yyyy-MM-dd hh:mm:ss"));
            disasterSituationMap.put("content", workBrief.getDisasterSituation());
            workInfoMap.get("disasterSituation").add(disasterSituationMap);
            Map<String, String> emergencyMap = new HashMap<>();
            emergencyMap.put("companyName", workBrief.getCompanyName());
            emergencyMap.put("date"
                    , DateUtil.format(workBrief.getReportTime(), "yyyy-MM-dd hh:mm:ss"));
            emergencyMap.put("content", workBrief.getEmergency());
            workInfoMap.get("emergency").add(emergencyMap);
            Map<String, String> emergencyHandleMap = new HashMap<>();
            emergencyHandleMap.put("companyName", workBrief.getCompanyName());
            emergencyHandleMap.put("date"
                    , DateUtil.format(workBrief.getReportTime(), "yyyy-MM-dd hh:mm:ss"));
            emergencyHandleMap.put("content", workBrief.getEmergencyHandle());
            workInfoMap.get("emergencyHandle").add(emergencyHandleMap);
            Map<String, String> emergencyAfterMap = new HashMap<>();
            emergencyAfterMap.put("companyName", workBrief.getCompanyName());
            emergencyAfterMap.put("date"
                    , DateUtil.format(workBrief.getReportTime(), "yyyy-MM-dd hh:mm:ss"));
            emergencyAfterMap.put("content", workBrief.getEmergencyAfter());
            workInfoMap.get("emergencyAfter").add(emergencyAfterMap);
        });
        return workInfoMap;
    }

    private void initWorkBriefMap(HashMap<String, List<Map<String, String>>> workInfoMap) {
        workInfoMap.put("defenseWork", new ArrayList<>());
        workInfoMap.put("dutyPeople", new ArrayList<>());
        workInfoMap.put("disasterSituation", new ArrayList<>());
        workInfoMap.put("emergency", new ArrayList<>());
        workInfoMap.put("emergencyHandle", new ArrayList<>());
        workInfoMap.put("emergencyAfter", new ArrayList<>());
    }

    private Date getMaxDate(List<EmgWorkBrief> emgWorkBriefs,int planPublicId) {
        List<EmgWorkBrief> publicWorkBriefs=new ArrayList<>();
        emgWorkBriefs.forEach(emgWorkBrief -> {
            if(emgWorkBrief.getStatus().equals(Constant.WorkBriefStatus.PUBLIC.getValue())){
                publicWorkBriefs.add(emgWorkBrief);
            }
        });
        if (CollectionUtil.isEmpty(publicWorkBriefs)) {
            if(planPublicId==0){
                return null;
            }else{
                EmgPlanPublic emgPlanPublic=emgPlanPublicMapper.selectByPrimaryKey(planPublicId);
                if(ObjectUtil.isNotNull(emgPlanPublic)){
                    return emgPlanPublic.getSignDate()==null?
                            emgPlanPublic.getCreateDate():emgPlanPublic.getSignDate();
                }
            }
            return null;
        }
        if (publicWorkBriefs.size() == 1) {
            return publicWorkBriefs.get(0).getReportTime()==null?null:publicWorkBriefs.get(0).getReportTime();
        }

        if (publicWorkBriefs.get(0).getReportTime().getTime()
                >= publicWorkBriefs.get(publicWorkBriefs.size() - 1).getReportTime().getTime()) {
            return publicWorkBriefs.get(0).getReportTime();
        } else {
            return publicWorkBriefs.get(publicWorkBriefs.size() - 1).getReportTime();
        }
    }

    /**
     * 添加工作简报时，要确认当前响应是否完结
     *
     * @return
     */
    private boolean isPlanPublicFinished(EmgWorkBrief emgWorkBrief) {
        EmgPlanPublic emgPlanPublic = emgPlanPublicMapper
                .selectByPrimaryKey(emgWorkBrief.getPlanPublicId());
        if (ObjectUtil.isNull(emgPlanPublic)) {
            return true;
        }

        return emgPlanPublic.getFinish();
    }
}
